package org.example.api;

import com.google.common.util.concurrent.RateLimiter;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class RateLimiterProxy implements InvocationHandler {
    private Object target;
    private RateLimiter rateLimiter;

    public RateLimiterProxy(Object target, double permitsPerSecond) {
        this.target = target;
        this.rateLimiter = RateLimiter.create(permitsPerSecond);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String threadName = Thread.currentThread().getName();
        rateLimiter.acquire();
        System.out.println(threadName + ":got a bucket token " + method.getName() + ", time=" + (System.currentTimeMillis() / 1000));
        return method.invoke(target, args);
    }

    public static <T> T newProxyInstance(T target, double permitsPerSecond) {
        return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new RateLimiterProxy(target, permitsPerSecond));
    }
}
